package com.baosight.xcyber.tm.re.observer;

import com.alibaba.fastjson.JSONObject;
import com.baosight.xcyber.tm.re.domain.UIServer;
import com.baosight.xcyber.tm.re.domain.UITreeNode;
import com.baosight.xcyber.tm.re.repository.ApplicationRepository;
import com.zeroc.Ice.Current;
import com.zeroc.IceGrid.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class NodeObserverI implements NodeObserver {
    public static Logger logger= LoggerFactory.getLogger(NodeObserverI.class);

    List<NodeDynamicInfo> nodeDynamicInfoList;

    @Autowired
    public ApplicationRepository applicationRepository;
    @Override
    public void nodeInit(NodeDynamicInfo[] nodeDynamicInfos, Current current) {
        System.out.println("nodeInit "+ Arrays.stream(nodeDynamicInfos).map(JSONObject::toJSONString));
        this.nodeDynamicInfoList=Arrays.asList(nodeDynamicInfos);
    }

    @Override
    public void nodeUp(NodeDynamicInfo nodeDynamicInfo, Current current) {
        System.out.println("nodeUp "+ nodeDynamicInfo);
    }

    @Override
    public void nodeDown(String s, Current current) {
        System.out.println("nodeDown "+ s);
    }

    @Override
    public void updateServer(String s, ServerDynamicInfo serverDynamicInfo, Current current) {
        System.out.println("updateServer "+ s+" "+JSONObject.toJSON(serverDynamicInfo));
        applicationRepository.getUiApplicationInfoList().stream()
                .filter(item-> s.equals(item.getName()))
                .forEach(item->setUITreeNodeRecursion(item,serverDynamicInfo)
                );
        applicationRepository.updateUiApplicationInfoList();
    }

    @Override
    public void updateAdapter(String s, AdapterDynamicInfo adapterDynamicInfo, Current current) {
        System.out.println("updateAdapter "+ s+" "+JSONObject.toJSON(adapterDynamicInfo));
        applicationRepository.getUiApplicationInfoList().stream()
                .filter(item-> s.equals(item.getName()))
                .forEach(item->setUIAdapterNodeRecursion(item,adapterDynamicInfo)
                );
        applicationRepository.updateUiApplicationInfoList();
    }

    public void updateNodeAndServer(List<UITreeNode> uiTreeNodeList){
        Map<String, UITreeNode> uiTreeMap = uiTreeNodeList.stream().collect(Collectors.toMap(UITreeNode::getName, item -> item));
        this.nodeDynamicInfoList.forEach(item->{
            NodeInfo info = item.info;
            String name = info.name;
            UITreeNode uiTreeNode = uiTreeMap.get(name);
            JSONObject paramInfo=(JSONObject) JSONObject.toJSON(info);
            uiTreeNode.getParam().putAll(paramInfo);
            item.servers.stream().forEach(serverDynamicInfo->
                    setUITreeNodeRecursion(uiTreeNode,serverDynamicInfo));
            item.adapters.stream().forEach(adapterDynamicInfo ->
                    setUIAdapterNodeRecursion(uiTreeNode,adapterDynamicInfo));
        });
    }

    public void setUITreeNodeRecursion(UITreeNode uiTreeNode,ServerDynamicInfo serverDynamicInfo){
        if("SERVER".equals(uiTreeNode.getType())&&serverDynamicInfo.id.equals(uiTreeNode.getName())){
            uiTreeNode.getParam().put("pid",serverDynamicInfo.pid);
            uiTreeNode.getParam().put("enabled",serverDynamicInfo.enabled);
            uiTreeNode.setStatus(serverDynamicInfo.state.toString());
        }else{
            uiTreeNode.getChildren().stream().forEach(item->setUITreeNodeRecursion(item,serverDynamicInfo));
        }
    }

    public void setUIAdapterNodeRecursion(UITreeNode uiTreeNode,AdapterDynamicInfo adapterDynamicInfo){
        if("ADAPTER".equals(uiTreeNode.getType())&&adapterDynamicInfo.id.equals(uiTreeNode.getName())){
            uiTreeNode.getParam().put("id",adapterDynamicInfo.id);
            uiTreeNode.getParam().put("endpoints",adapterDynamicInfo.proxy.ice_getEndpoints());
        }else{
            uiTreeNode.getChildren().stream().forEach(item->setUIAdapterNodeRecursion(item,adapterDynamicInfo));
        }
    }
}
